package com.github.m6d21.sso.support.hander;

import static com.github.m6d21.sso.support.enums.StatusCode.REQUEST_PARAM_ERROR;
import static com.github.m6d21.sso.support.enums.StatusCode.SYSTEM_ERROR;

import com.github.m6d21.sso.core.exception.BusinessException;
import com.github.m6d21.sso.core.exception.LoginException;
import com.github.m6d21.sso.core.exception.ParamException;
import com.github.m6d21.sso.support.model.Response;
import com.github.m6d21.sso.support.util.ResponseUtil;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 *<p>
 *统一异常处理
 *</p>
 *
 * @author liuyang03
 * @date 2018-11-19 Mon 13:00:32
 * @since 1.0.0
 */
@ControllerAdvice
public class ExceptionDealHandler {

    private final static Logger LOG = LoggerFactory.getLogger(ExceptionDealHandler.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Response handle(Exception e) {
        if (e instanceof BusinessException) {
            return ResponseUtil.fail(((BusinessException) e).getCode(), e.getMessage());
        } else if (e instanceof ParamException) {
            return ResponseUtil.fail(((ParamException) e).getCode(), e.getMessage());
        } else if (e instanceof ConstraintViolationException) {
            String msg = processConstraintViolationExceptionMsg((ConstraintViolationException) e);
            return ResponseUtil.fail(REQUEST_PARAM_ERROR.getCode(), msg);
        } else if (e instanceof LoginException) {
            return ResponseUtil.fail(((LoginException) e).getCode(), e.getMessage());
        } else {
            LOG.error("[系统异常]" + e.getMessage(), e);
            return ResponseUtil.fail(SYSTEM_ERROR.getCode(), e.getMessage());
        }
    }

    /**
     *ConstraintViolationException的message会把校验失败的参数信息附加到错误
     * 消息中，这里移除参数信息，只返回定义的模板信息
     *
     * @author liuyang
     * @date 2018-12-06 Thu 11:19:46
     * @param e ConstraintViolationException
     */
    private String processConstraintViolationExceptionMsg(ConstraintViolationException e) {
        Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
        StringBuilder msg = new StringBuilder("");
        for (ConstraintViolation c : constraintViolations) {
            if (StringUtils.isNotBlank(c.getMessageTemplate())) {
                msg.append(c.getMessageTemplate()).append(";");
            }
        }
        return msg.toString();
    }
}
